package com.xcity.game.mail;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.alibaba.fastjson.annotation.JSONField;
import com.xcity.db.entity.Player;
import com.xcity.game.common.Cause;
import com.xcity.game.item.ItemInfo;
import com.xcity.game.item.ItemService;
import com.xcity.game.item.drop.Drop;
import com.xcity.game.item.drop.listener.MultiDropAdapter;
import com.xcity.pomelo.push.msg.BatchItemsPush;

/**
 * 邮件附件
 * @author YangLi
 *
 */
public class MailAttach {

	protected int gold;
	protected int stone;
	protected int exp;
	protected List<ItemInfo> items;
	
	public MailAttach() {}
	
	public MailAttach(int gold, int stone) {
		this(gold, stone, 0);
	}
	
	public MailAttach(int gold, int stone, int exp) {
		this(gold, stone, exp, null);
	}
	
	public MailAttach(int gold, int stone, int exp, List<ItemInfo> items) {
		this.gold = gold;
		this.stone = stone;
		this.items = items;
	}

	public int getGold() {
		return gold;
	}

	public void setGold(int gold) {
		this.gold = gold;
	}

	public int getStone() {
		return stone;
	}

	public void setStone(int stone) {
		this.stone = stone;
	}

	public int getExp() {
		return exp;
	}

	public void setExp(int exp) {
		this.exp = exp;
	}

	public List<ItemInfo> getItems() {
		return items;
	}

	public void setItems(List<ItemInfo> items) {
		this.items = items;
	}
	
	public void addExp(int val) {
		this.exp += val;
	}
	
	public void addGold(int val) {
		this.gold += val;
	}
	
	public void addStone(int val) {
		this.stone += val;
	}
	
	public void addItem(int id, int count) {
		addItem(id, count, false);
	}
	
	public void addItem(int id, int count, boolean unique) {
		if (items == null) {
			items = new ArrayList<ItemInfo>(2);
		}
		if (unique) {
			addItem1(id, count);
		} else {
			addItem0(id, count);
		}
	}
	
	private void addItem0(int id, int count) {
		items.add(new ItemInfo(id, count));
	}
	
	private void addItem1(int id, int count) {
		ItemInfo item = null;
		for (int i = items.size() - 1; i >= 0; i--) {
			ItemInfo ref = items.get(i);
			if (ref.getId() == id) {
				item = ref;
				break;
			}
		}
		if (item == null) {
			item = new ItemInfo(id, 0);
			items.add(item);
		}
		item.setCount(item.getCount() + count);
	}
	
	public void addDrop(Drop drop) {
		drop.drop(Drop.RND, null, Cause.MAIL_ATTACH, new MultiDropAdapter() {
			@Override
			public void expDroped(Player player, int exp) {
				addExp(exp);
			}
			@Override
			public void goldDroped(Player player, int gold) {
				addGold(gold);
			}
			@Override
			public void stoneDroped(Player player, int stone) {
				addStone(stone);
			}
			@Override
			public void itemDroped(Player player, int itemId, int count) {
				addItem(itemId, count, true);
			}
		});
	}
	
	public void addBatch(Collection<ItemInfo> batch) {
		if (items == null) {
			items = new ArrayList<ItemInfo>(batch.size());
		}
		for (ItemInfo item : batch) {
			items.add(new ItemInfo(item.getTemplate(), item.getCount()));
		}
	}
	
	public void receive(Player player, String cause, boolean notify) {
		if (notify) {
			receiveAndNotify(player, cause);
		} else {
			receiveWithoutNotify(player, cause);
		}
	}
	
	private void receiveAndNotify(Player player, String cause) {
		BatchItemsPush sync = new BatchItemsPush();
		int val = getGold();
		if (val > 0) {
			sync.addGold(val);
			player.addGold(val, cause);
		}
		val = getStone();
		if (val > 0) {
			sync.addStone(val);
			player.addStone(val, cause);
		}
		val = getExp();
		if (val > 0) {
			player.addExp(val, cause);
		}
		List<ItemInfo> items = getItems();
		if (items != null) {
			for (int i = 0, size = items.size(); i < size; i++) {
				ItemInfo item = items.get(i);
				boolean succ = player.getBag().addItemWithoutException(item.getId(), item.getCount(), cause);
				if (succ) {
					sync.add(item.getTemplate(), item.getCount());
				}
			}
		}
		player.send(sync);
	}
	
	private void receiveWithoutNotify(Player player, String cause) {
		int val = getGold();
		if (val > 0) {
			player.addGold(val, cause);
		}
		val = getStone();
		if (val > 0) {
			player.addStone(val, cause);
		}
		val = getExp();
		if (val > 0) {
			player.addExp(val, cause);
		}
		List<ItemInfo> items = getItems();
		if (items != null) {
			for (int i = 0, size = items.size(); i < size; i++) {
				ItemInfo item = items.get(i);
				player.getBag().addItemWithoutException(item.getId(), item.getCount(), cause);
			}
		}
	}
	
	@JSONField(serialize = false)
	public boolean isEmpty() {
		return gold <= 0 && stone <= 0 && (items == null || items.isEmpty());
	}
	
	/**
	 * 转换为客户端显示需要的数据
	 * @return
	 */
	public List<ItemInfo> convert() {
		int size = items != null ? items.size() : 0;
		List<ItemInfo> list = new ArrayList<ItemInfo>(size + 2);
		if (gold > 0) {
//			list.add(new ItemResponse(ItemService.goldDefault, gold));
			list.add(new ItemInfo(ItemService.goldDefault, gold));
		}
		if (stone > 0) {
//			list.add(new ItemResponse(ItemService.stoneDefault, stone));
			list.add(new ItemInfo(ItemService.stoneDefault, stone));
		}
		for (int i = 0; i < size; i++) {
//			list.add(new ItemResponse(items.get(i)));
			list.add(items.get(i));
		}
		return list;
	}
	
}
